  /**
   * WebSocket 单例服务
   * 提供全局唯一的 WebSocket 连接，支持多处监听和使用
   */
  class WebSocketService {
    constructor() {
      // 单例实例
      if (WebSocketService.instance) {
        return WebSocketService.instance
      }

      // WebSocket 实例
      this.ws = null
      this.url = ''

      // 连接状态
      this.connected = false
      this.connecting = false

      // 重连配置
      this.reconnectAttempts = 0
      this.maxReconnectAttempts = 5
      this.reconnectInterval = 3000
      this.reconnectTimer = null

      // 心跳配置
      this.heartbeatTimer = null
      this.heartbeatInterval = 600000 // 10分钟

      // 事件监听器
      this.messageListeners = new Set()
      this.connectionListeners = new Set()
      this.errorListeners = new Set()

      // 消息队列 (连接断开时暂存消息)
      this.messageQueue = []

      WebSocketService.instance = this
    }

    /**
     * 初始化 WebSocket 连接
     * @param {string} wsUrl WebSocket URL
     */
    init(wsUrl) {
      if (this.connected || this.connecting) {
        console.log('[WebSocket] 已连接或正在连接中')
        return Promise.resolve()
      }

      this.url = wsUrl
      return this.connect()
    }

    /**
     * 建立连接
     */
    connect() {
      return new Promise((resolve, reject) => {
        try {
          this.connecting = true
          this.ws = new WebSocket(this.url)

          // 连接成功
          this.ws.onopen = () => {
            console.log('[WebSocket] 连接已建立:', this.url)
            this.connected = true
            this.connecting = false
            this.reconnectAttempts = 0

            // 开始心跳
            this.startHeartbeat()

            // 发送队列中的消息
            this.flushMessageQueue()

            // 通知连接监听器
            this.notifyConnectionListeners('connected')

            resolve()
          }

          // 接收消息
          this.ws.onmessage = (event) => {
            try {
              const data = JSON.parse(event.data)
              console.log('[WebSocket] 收到消息:', data)

              // 处理心跳响应
              if (data.type === 'heartbeat') {
                console.log('[WebSocket] 心跳响应正常')
                return
              }

              // 通知消息监听器
              this.notifyMessageListeners(data)
            } catch (error) {
              console.error('[WebSocket] 解析消息失败:', error, event.data)
              // 对于非 JSON 消息，直接传递原始数据
              this.notifyMessageListeners(event.data)
            }
          }

          // 连接关闭
          this.ws.onclose = (event) => {
            console.log('[WebSocket] 连接已关闭:', event.code, event.reason)
            this.connected = false
            this.connecting = false
            this.stopHeartbeat()

            // 通知连接监听器
            this.notifyConnectionListeners('disconnected', event)

            // 如果不是主动关闭，尝试重连
            if (event.code !== 1000 && this.reconnectAttempts < this.maxReconnectAttempts) {
              this.scheduleReconnect()
            } else if (this.reconnectAttempts >= this.maxReconnectAttempts) {
              console.error('[WebSocket] 重连次数已达上限，停止重连')
              this.notifyErrorListeners(new Error('WebSocket 重连次数已达上限'))
            }
          }

          // 连接错误
          this.ws.onerror = (error) => {
            console.error('[WebSocket] 连接错误:', error)
            this.connected = false
            this.connecting = false
            this.notifyErrorListeners(error)
            reject(error)
          }
        } catch (error) {
          console.error('[WebSocket] 创建连接失败:', error)
          this.connecting = false
          this.notifyErrorListeners(error)
          reject(error)
        }
      })
    }

    /**
     * 安排重连
     */
    scheduleReconnect() {
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer)
      }

      this.reconnectAttempts++
      console.log(`[WebSocket] 尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`)

      this.reconnectTimer = setTimeout(() => {
        this.connect().catch((error) => {
          console.error('[WebSocket] 重连失败:', error)
        })
      }, this.reconnectInterval)
    }

    /**
     * 开始心跳
     */
    startHeartbeat() {
      this.stopHeartbeat()
      this.heartbeatTimer = setInterval(() => {
        if (this.connected && this.ws && this.ws.readyState === WebSocket.OPEN) {
          this.send({ type: 'heartbeat', timestamp: Date.now() })
        }
      }, this.heartbeatInterval)
    }

    /**
     * 停止心跳
     */
    stopHeartbeat() {
      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer)
        this.heartbeatTimer = null
      }
    }

    /**
     * 发送消息
     * @param {Object|string} data 要发送的数据
     */
    send(data) {
      const message = typeof data === 'string' ? data : JSON.stringify(data)

      if (this.connected && this.ws && this.ws.readyState === WebSocket.OPEN) {
        this.ws.send(message)
        console.log('[WebSocket] 发送消息:', data)
      } else {
        console.warn('[WebSocket] 连接未建立，消息加入队列:', data)
        this.messageQueue.push(message)
      }
    }

    /**
     * 发送队列中的消息
     */
    flushMessageQueue() {
      if (this.messageQueue.length > 0) {
        console.log(`[WebSocket] 发送队列中的 ${this.messageQueue.length} 条消息`)
        this.messageQueue.forEach((message) => {
          if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(message)
          }
        })
        this.messageQueue = []
      }
    }

    /**
     * 添加消息监听器
     * @param {Function} listener 监听器函数
     */
    addMessageListener(listener) {
      this.messageListeners.add(listener)
      console.log(`[WebSocket] 添加消息监听器，当前监听器数量: ${this.messageListeners.size}`)
    }

    /**
     * 移除消息监听器
     * @param {Function} listener 监听器函数
     */
    removeMessageListener(listener) {
      this.messageListeners.delete(listener)
      console.log(`[WebSocket] 移除消息监听器，当前监听器数量: ${this.messageListeners.size}`)
    }

    /**
     * 添加连接状态监听器
     * @param {Function} listener 监听器函数 (status, event) => {}
     */
    addConnectionListener(listener) {
      this.connectionListeners.add(listener)
    }

    /**
     * 移除连接状态监听器
     * @param {Function} listener 监听器函数
     */
    removeConnectionListener(listener) {
      this.connectionListeners.delete(listener)
    }

    /**
     * 添加错误监听器
     * @param {Function} listener 监听器函数
     */
    addErrorListener(listener) {
      this.errorListeners.add(listener)
    }

    /**
     * 移除错误监听器
     * @param {Function} listener 监听器函数
     */
    removeErrorListener(listener) {
      this.errorListeners.delete(listener)
    }

    /**
     * 通知消息监听器
     * @param {*} data 消息数据
     */
    notifyMessageListeners(data) {
      this.messageListeners.forEach((listener) => {
        try {
          listener(data)
        } catch (error) {
          console.error('[WebSocket] 消息监听器执行错误:', error)
        }
      })
    }

    /**
     * 通知连接状态监听器
     * @param {string} status 连接状态
     * @param {*} event 事件对象
     */
    notifyConnectionListeners(status, event = null) {
      this.connectionListeners.forEach((listener) => {
        try {
          listener(status, event)
        } catch (error) {
          console.error('[WebSocket] 连接状态监听器执行错误:', error)
        }
      })
    }

    /**
     * 通知错误监听器
     * @param {Error} error 错误对象
     */
    notifyErrorListeners(error) {
      this.errorListeners.forEach((listener) => {
        try {
          listener(error)
        } catch (error) {
          console.error('[WebSocket] 错误监听器执行错误:', error)
        }
      })
    }

    /**
     * 关闭连接
     */
    close() {
      console.log('[WebSocket] 主动关闭连接')

      // 停止重连
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer)
        this.reconnectTimer = null
      }

      // 停止心跳
      this.stopHeartbeat()

      // 关闭连接
      if (this.ws) {
        this.ws.close(1000, '应用关闭')
        this.ws = null
      }

      this.connected = false
      this.connecting = false
      this.reconnectAttempts = 0

      // 清空消息队列
      this.messageQueue = []
    }

    /**
     * 获取连接状态
     */
    isConnected() {
      return this.connected
    }

    /**
     * 获取重连次数
     */
    getReconnectAttempts() {
      return this.reconnectAttempts
    }

    /**
     * 重置重连次数
     */
    resetReconnectAttempts() {
      this.reconnectAttempts = 0
    }
  }

  // 导出单例实例
  const wsService = new WebSocketService()

  // 导出便捷方法
  export default wsService

  export const {
    init: initWebSocket,
    send: sendMessage,
    addMessageListener,
    removeMessageListener,
    addConnectionListener,
    removeConnectionListener,
    addErrorListener,
    removeErrorListener,
    close: closeWebSocket,
    isConnected,
    getReconnectAttempts,
    resetReconnectAttempts,
  } = wsService
